package com.elh.nio;

import org.junit.jupiter.api.Test;

import java.nio.*;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @author liulei
 **/
public class ByteBufferTest {

    @Test
    public void demo1() {
        // DirectByteBuffer
        ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(100);
        System.out.println("position = " + byteBuffer1.position() + "limit = " + byteBuffer1.limit() + "");
        // HeapByteBuffer
        ByteBuffer byteBuffer2 = ByteBuffer.allocate(200);
        System.out.println("position = " + byteBuffer2.position() + "limit = " + byteBuffer2.limit() + "");
    }

    @Test
    public void demo2() {
        long start = System.currentTimeMillis();
        ByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(1900000000);
        for (int i = 0; i < 1900000000; i++) {
            byteBuffer1.put((byte) 123);
        }
        long end = System.currentTimeMillis();
        // 1201
        System.out.println(end - start);
    }

    @Test
    public void demo3() {
        long start = System.currentTimeMillis();
        ByteBuffer byteBuffer1 = ByteBuffer.allocate(1900000000);
        for (int i = 0; i < 1900000000; i++) {
            byteBuffer1.put((byte) 123);
        }
        // 1632
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

    @Test
    public void demo4() {
        byte[] byteArray = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
        ByteBuffer wrap1 = ByteBuffer.wrap(byteArray);
//        ByteBuffer wrap2 = ByteBuffer.wrap(byteArray,2,4);
        System.out.println("limit1 = " + wrap1.limit() + " capacity = " + wrap1.capacity() + " position = " + wrap1.position());
        // limit = offset + length
//        System.out.println("limit2 = " + wrap2.limit() + " capacity = " + wrap2.capacity() + " position = " + wrap2.position());
    }

    @Test
    public void demo5() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        byteBuffer.put((byte) 123);
        // position增加
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        // position增加
        byteBuffer.put((byte) 124);
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        // position = 0,重新读取缓存区
        byteBuffer.rewind();
        /**
         *  position = 0;
         *  limit = capacity;
         */
        // 在对缓存区存储之前调用
//        byteBuffer.clear();
        System.out.println(byteBuffer.get());
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
//        byteBuffer.remaining();
    }


    @Test
    public void demo6() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(10);
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        byteBuffer.put((byte) 123);
        // position增加
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        // position增加
        byteBuffer.put((byte) 124);
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
        // position = 0,重新读取缓存区
        byteBuffer.rewind();
        /**
         *  position = 0;
         *  limit = capacity;
         */
        // 在对缓存区存储之前调用
//        byteBuffer.clear();
        System.out.println(byteBuffer.get());
        System.out.println("limit1 = " + byteBuffer.limit() + " capacity = " + byteBuffer.capacity() + " position = " + byteBuffer.position());
//        byteBuffer.remaining();
    }

    @Test
    public void demo7() {
        byte[] array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        byte[] array2 = {55, 66, 77, 88};
        //分配10个空间
        ByteBuffer buffer = ByteBuffer.allocate(10);
        //将array1传入缓冲区
        buffer.put(array1);
        //位置定位到2
        buffer.position(2);
        //array2的数据传入缓冲区的2到4号位置
        buffer.put(array2, 1, 3);
        //打印
        System.out.println(Arrays.toString(buffer.array()));
        byte[] array3 = new byte[buffer.capacity()];
        //将缓冲区当前位置的数据传输到，目标数组的3到6号位置
        buffer.get(array3, 3, 4);
        System.out.println(Arrays.toString(array3));
    }

    //
    @Test
    public void demo8() {
        byte[] array1 = {1, 2, 3, 4, 5, 6, 7, 8, 9};
        ByteBuffer buffer = ByteBuffer.allocate(10);
        buffer.put(array1);
        buffer.put(2, (byte) 125);
        System.out.println(buffer.get(2));
        buffer.position(0);
        byte[] array2 = new byte[buffer.capacity()];
        buffer.get(array2, 0, array2.length);
        System.out.println(Arrays.toString(array2));
    }

    //
    @Test
    public void demo9() {
        byte[] array1 = {1, 2, 3, 4, 5, 6, 7, 8};
        ByteBuffer buffer1 = ByteBuffer.wrap(array1);
        byte[] array2 = {55, 66, 77};
        ByteBuffer buffer2 = ByteBuffer.wrap(array2);
        buffer2.slice();
        buffer1.position(4);
        buffer2.position(1);
        buffer1.put(buffer2);
        System.out.println("buffer1被改变" + buffer1.position());
        System.out.println("buffer2被改变" + buffer2.position());
        System.out.println(Arrays.toString(buffer1.array()));
        System.out.println(Arrays.toString(buffer2.array()));
    }

    @Test
    public void demo10() {
        byte[] array1 = {1, 2, 3, 4, 5, 6, 7, 8};
        ByteBuffer buffer = ByteBuffer.wrap(array1);
        buffer.position(5);
        ByteBuffer slice = buffer.slice();
        System.out.println("buffer1 capacity = " + buffer.capacity() +
                " limit=" + buffer.limit() + " position=" + buffer.position());
        System.out.println("slice capacity = " + slice.capacity() +
                " limit=" + slice.limit() + " position=" + slice.position());
        System.out.println(Arrays.toString(buffer.array()));
        System.out.println(Arrays.toString(slice.array()));
    }

    //
    @Test
    public void demo11(){
        // 将中文转为字节数组
        byte[] byteArray = "我是中国人".getBytes();
        System.out.println(Charset.defaultCharset().name());
        // 将字节数组转为字节缓存区,编码为UTF-8
        ByteBuffer byteBuffer = ByteBuffer.wrap(byteArray);
        System.out.println("bytebuffer = " + byteBuffer.getClass().getName());
        // 将编码格式UTF-8转为UTF-8的CharBuffer
        CharBuffer charBuffer = byteBuffer.asCharBuffer();
        System.out.println("charBuffer = " + charBuffer.getClass().getName());
        System.out.println("position = " + byteBuffer.position() + "capacity = " + byteBuffer.capacity() + "limit = " + byteBuffer.limit());
        for (int i = 0; i < charBuffer.capacity(); i++) {
            System.out.println(charBuffer.get());
        }
    }

    /**
     * 创建视图缓存区
     *
     */
    @Test
    public void demo12(){
//        ByteBuffer byteBuffer = ByteBuffer.allocate(32);
//        byteBuffer.putDouble(1.1D);
//        byteBuffer.putDouble(1.2D);
//        byteBuffer.flip();
//        DoubleBuffer doubleBuffer = byteBuffer.asDoubleBuffer();
//        for (int i = 0; i < doubleBuffer.capacity(); i++) {
//            System.out.println(doubleBuffer.get(i) + "");
//        }
        ByteBuffer byteBuffer2 = ByteBuffer.allocate(16);
        byteBuffer2.putFloat(1.1F);
        byteBuffer2.putFloat(1.2F);
        byteBuffer2.flip();
        FloatBuffer floatBuffer = byteBuffer2.asFloatBuffer();
        for (int i = 0; i < floatBuffer.capacity(); i++) {
            System.out.println(floatBuffer.get(i) + "");
        }
    }

    @Test
    public void demo13(){
        IntBuffer intBuffer = IntBuffer.allocate(10);
        intBuffer.put(456);
        System.out.println("B1 = " + intBuffer.position());
        intBuffer.put(789);
        System.out.println("B1 = " + intBuffer.position());
        intBuffer.flip();
    }

    @Test
    public void demo14(){
        byte[] bytes = {1,2,3,4};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(bytes);
        byteBuffer1.compact();
        ByteBuffer byteBuffer2 = byteBuffer1.asReadOnlyBuffer();
        System.out.println("byteBuffer1.isReadOnly()=" + byteBuffer1.isReadOnly());
        System.out.println("byteBuffer2.isReadOnly()=" + byteBuffer2.isReadOnly());
        byteBuffer2.rewind();
        byteBuffer2.put((byte)123);
    }

    @Test
    public void demo15(){
        byte[] bytes = {1,2,3,4};
        ByteBuffer byteBuffer1 = ByteBuffer.wrap(bytes);
        byteBuffer1.position(2);
        byteBuffer1.duplicate();
        byteBuffer1.slice();
    }

    @Test
    public void demo16(){
        CharBuffer charBuffer = CharBuffer.allocate(15);
        System.out.println("A " + charBuffer.position());
        charBuffer.append('a');
        System.out.println("B " + charBuffer.position());
        char[] array = charBuffer.array();
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i] + " ");
        }
    }

    @Test
    public void demo17(){
        CharBuffer charBuffer = CharBuffer.allocate(15);
        charBuffer.append("abcdefg");
        charBuffer.position(2);
        System.out.println(charBuffer.charAt(0));
        System.out.println(charBuffer.charAt(1));
    }




}
